﻿using System.Collections.Generic;
using System.Globalization;

namespace CSW.Framework.Common.Utils.StringUtils
{
    /// <summary>
    /// StringConverter static class.
    /// </summary>
    public static class StringConverter
    {
        /// <summary>
        /// Gets the "pretty" name of a pascal cased string. Separates words based on capital
        /// letters and non-letter characters.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>The "pretty" name.</returns>
        public static string GetPrettyName(string input)
        {
            if (string.IsNullOrEmpty(input) || !char.IsUpper(input[0]))
                return input;

            // Split words based on casing
            List<string> words = new List<string>();
            int oldIndex = 0;
            bool lastWasNotLetter = false;
            for (int i = 1; i < input.Length; i++)
            {
                char c = input[i];

                if (char.IsUpper(c) ||
                    (!char.IsLetter(c) && !lastWasNotLetter) ||
                    (char.IsLetter(c) && lastWasNotLetter))
                {
                    lastWasNotLetter = !char.IsLetter(c);
                    string newWord = input.Substring(oldIndex, i - oldIndex);
                    words.Add(newWord);
                    oldIndex = i;
                }
            }

            words.Add(input.Substring(oldIndex));

            if (words.Count == 0)
                return input;

            // Put words back together
            input = string.Empty;
            for (int i = 0; i < words.Count; i++)
            {
                string word = words[i];

                if (word == ".")
                    continue;

                if (i == 0 && words.Count > 1 && word.EndsWith("_"))
                    continue;

                if (i > 0 && words[i - 1].Length == 1 && word.Length == 1)
                {
                    input += word;
                }
                else
                {
                    if (string.IsNullOrEmpty(input))
                        input = word;
                    else
                        input += " " + word;
                }
            }

            return input;
        }

        /// <summary>
        /// Converts currency text to a double value.
        /// </summary>
        /// <param name="displayText">The display text.</param>
        /// <returns>The double value.</returns>
        public static double? GetCurrencyAsDoubleOrNull(string displayText)
        {
            if (displayText == null)
                return null;

            bool isMillions = false;
            if (displayText.EndsWith("m", true, CultureInfo.InvariantCulture))
            {
                isMillions = true;
                displayText = displayText.Substring(0, displayText.Length - 1);
            }

            bool isThousands = false;
            if (displayText.EndsWith("k", true, CultureInfo.InvariantCulture))
            {
                isThousands = true;
                displayText = displayText.Substring(0, displayText.Length - 1);
            }

            double amount;
            string parseText = displayText.Replace("$", "").Replace(",", "").Replace("(", "-").Replace(")", "");
            if (double.TryParse(parseText, out amount))
            {
                if (isMillions)
                    return amount * 1000000;
                else if (isThousands)
                    return amount * 1000;
                else
                    return amount;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Converts a percent to a double value.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns>The double value.</returns>
        public static double? GetPercentAsDoubleOrNull(string text)
        {
            if (text == null)
                return null;

            text = text.Replace("%", "");

            double amount;
            if (double.TryParse(text, out amount))
                return amount / 100.0;
            else
                return null;
        }

        /// <summary>
        /// Converts the string to an Int32 or null.
        /// </summary>
        /// <param name="value">The value.</param>
        public static int? GetInt32OrNull(string value)
        {
            if (value == null || value.Trim() == "")
                return null;

            int result;
            if (int.TryParse(value, out result) == false)
                return null;
            else
                return result;
        }

        /// <summary>
        /// Converts the string to a double or null.
        /// </summary>
        /// <param name="value">The value.</param>
        public static double? GetDoubleOrNull(string value)
        {
            if (value == null || value.Trim() == "")
                return null;

            double result;
            if (double.TryParse(value, out result) == false)
                return null;
            else
                return result;
        }

        /// <summary>
        /// Converts the first characters to uppercase and the remaining characters to lowercase.
        /// </summary>
        /// <param name="text">The text.</param>
        public static string GetSentenceCase(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                if (text.Length > 1)
                    text = text.Substring(0, 1).ToUpper() + text.Substring(1, text.Length - 1).ToLower();
                else
                    text = text.ToUpper();
            }

            return text;
        }
    }
}